package utils

/*
**

	效率不如map, 建议使用map
*/
type KVRec struct {
	Key interface{}
	Val interface{}
}

type KVMap struct {
	rangeflag byte
	lst       []*KVRec
}

func NewKVMap(capacity int) *KVMap {
	rval := &KVMap{
		lst: make([]*KVRec, 0, capacity),
	}
	return rval
}

func (this *KVMap) Capacity() int {
	return cap(this.lst)
}

func (this *KVMap) Count() int {
	return len(this.lst)
}

func (this *KVMap) FindIdx(key interface{}) int {
	for i := 0; i < len(this.lst); i++ {
		if this.lst[i].Key == key {
			return i
		}
	}
	return -1
}

func (this *KVMap) Find(key interface{}) *KVRec {
	for i := 0; i < len(this.lst); i++ {
		if this.lst[i].Key == key {
			return this.lst[i]
		}
	}
	return nil
}

func (this *KVMap) Set(key, val interface{}) {
	rec := this.Find(key)
	if rec == nil {
		rec = &KVRec{key, val}
		this.lst = append(this.lst, rec)
	} else {
		rec.Val = val
	}
}

func (this *KVMap) Remove(key interface{}) bool {
	if this.rangeflag == 1 {
		panic("map in range!!!")
	}
	i := this.FindIdx(key)
	if i == -1 {
		return false
	} else {
		lst := this.lst
		this.lst = append(lst[:i], lst[i+1:]...)
		return true
	}
}

/*
**

	注意:
	 	请勿在回调中进行Remove操作
*/
func (this *KVMap) Range(cb func(key, val interface{}) bool) {
	this.rangeflag = 1
	for i := 0; i < len(this.lst); i++ {
		rec := this.lst[i]
		if !cb(rec.Key, rec.Val) {
			break
		}
	}
	this.rangeflag = 0
}

func (this *KVMap) Get(key interface{}, def interface{}) interface{} {
	rec := this.Find(key)
	if rec == nil {
		return def
	} else {
		return rec.Val
	}
}
